package android.matrix;

/**
 * La clase abstracta AbstractMatrix es la plantilla para las matrices a ser 
 * utilizadas en la aplicación. Esta establece los parámetros básicos que toda
 * clase de matrices debe contener.
 * 
 * @author Rafael Asprilla
 *
 */
public abstract class AbstractMatrix {
	
	/**
	 * Atributo que contiene el nombre por defecto del archivo de matriz para 
	 * el objeto actual.
	 */
	protected String filename;
	
	/**
	 * Atributo que cuenta la cantidad de instancias de la clase RemoteMatrix 
	 * existentes en la aplicación actual.
	 */
	private static int matcnt = 0;
	
	/**
	 * Contiene los valores numéricos de los elementos de la matriz.
	 */
	protected float element[][];
	/**
	 * Contienen el tamaño de las filas y columnas de la matriz.
	 */
	public int rows, columns;
	
	/**
	 * Representación en cadena de caracteres del contenido de la matriz.
	 */
	protected int matnum;
	
	/**
	 * Constructor de la clase <code>AbstracMatrix</code>
	 * 
	 * @param rows 
	 * Número de filas de la matriz.
	 * @param columns 
	 * Número de columnas de la matriz.
	 */
	protected AbstractMatrix(int rows, int columns)
	{
		this.element = new float[rows][columns];
		this.rows = rows;
		this.columns = columns;
		matnum = matcnt;
		filename = String.format("mat%03d.mat", matnum);
		matcnt++;
	}
	
	/**
	 * Constructor de la clase <code>AbstracMatrix</code>
	 * 
	 * @param e 
	 * Es un arreglo que contiene los elementos de la matriz.
	 */
	protected AbstractMatrix(float[][] e)
	{
		this.element = e;
		this.rows = e.length;
		this.columns = e[0].length;
		matnum = matcnt;
		filename = String.format("mat%03d.mat", matnum);
		matcnt++;
	}
	
	/**
	 * Constructor de la clase <code>AbstracMatrix</code>
	 */
	protected AbstractMatrix() {
		matnum = matcnt;
		filename = String.format("mat%03d.mat", matnum);
		matcnt++;
	}

	
	/**
	 * @return El nombre de archivo
	 */
	public final String getFilename() {
		return filename;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString()
	{
		StringBuilder tmp = new StringBuilder("");
		for(int i = 0; i < rows; i++)
		{
			for(int j = 0; j < columns; j++)
			{
				tmp.append(element[i][j]);
				tmp.append(", ");
			}
			tmp.append("\n");
		}
		return tmp.toString();
	}
	
	/**
	 * El método getColumn(int) devuelve una columna de la matriz.
	 * 
	 * @param index
	 * Número de columna solicitado.
	 * @return
	 * Devuelve un arreglo float[] que contiene el valor de la columna solicitada.
	 */
	public float[] getColumn(int index)
	{
		float column[] = new float[element[0].length];
		
		for(int i = 0; i < element[0].length; i++)
			column[i] = element[i][index];
		
		return column;
	}
	
	/**
	 * El método getElement permite acceder a los elementos de la matriz de forma individual.
	 * 
	 * @param x
	 * Posición horizontal del elemento.
	 * @param y
	 * Posición vertical del elemento.
	 * @return
	 * Devuelve un float con el valor del elemento element[x][y].
	 */
	public float getElement(int x, int y) 
	{
		return element[x][y];
	}
	
	/**
	 * El método getRow(int) devuelve una fila de la matriz.
	 * 
	 * @param index
	 * Número de fila solicitado.
	 * @return
	 * Devuelve un arreglo float[] que contiene el valor de la fila solicitada.
	 */
	public float[] getRow(int index)
	{
		return element[index];
	}
}
